package com.ouc.zykt.filter;
import com.ouc.openplatform.pampas.SessionManager;
import com.ouc.pampas.ClusterHttpServletRequestWrapper;
import com.ouc.pampas.ClusterHttpSessionWrapper;
import com.ouc.pampas.IpUtil;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class ClusterSessionFilter implements Filter
{
  private static final Log LOG = LogFactory.getLog(ClusterSessionFilter.class);
  private String sessionKey = "sid";
  private String cookieDomain;
  private String cookiePath;
  //忽略的uri
  private Pattern requestUriIgnorePattern;
  private SessionManager sessionService;
  private ServletContext servletContext;
  
  public void init(FilterConfig filterConfig) throws ServletException
  {
    this.servletContext = filterConfig.getServletContext();
    Map<String, String> initMap = new HashMap<String, String>();
    for (Enumeration<String> enu = filterConfig.getInitParameterNames(); enu.hasMoreElements();)
    {
      String key = (String)enu.nextElement();
      initMap.put(key, filterConfig.getInitParameter(key));
    }
    String contextPath = filterConfig.getServletContext().getContextPath();
    String path = null;
    System.out.println("contextPath的值为" + contextPath);
    if (contextPath.startsWith("/")) {
      path = contextPath.substring(1);
    } else {
      path = "sid";
    }
    this.sessionKey = StringUtils.defaultIfEmpty((String)initMap.get("sessionKey"), path + "_sessionId");
    this.cookieDomain = StringUtils.defaultIfEmpty((String)initMap.get("cookieDomain"), "");
    this.cookiePath = StringUtils.defaultIfEmpty((String)initMap.get("cookiePath"), "/");
    ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext());
    String sessionServiceId = StringUtils.defaultIfEmpty((String)initMap.get("sessionServiceId"), "sessionService");
    System.out.println("sessionServiceId为"+sessionServiceId);
    this.sessionService = ((SessionManager)applicationContext.getBean(sessionServiceId, SessionManager.class));
    //从配置文件中读取一个正则表达式
    String ignorUrlPattern = StringUtils.defaultIfEmpty((String)initMap.get("requestUriIgnorePattern"), "");
    this.requestUriIgnorePattern = Pattern.compile(ignorUrlPattern, 2);
    LOG.info("SessionFilter初始完成" + initMap);
  }
  
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
    throws IOException, ServletException
  {
    HttpServletRequest request = (HttpServletRequest)servletRequest;
    HttpServletResponse response = (HttpServletResponse)servletResponse;
   
    String requestUrl = request.getRequestURI();
    if (this.requestUriIgnorePattern.matcher(requestUrl).matches())
    {
      chain.doFilter(servletRequest, servletResponse);
      return;
    }
    Cookie[] cookies = request.getCookies();
    String sid = "";
    //从cookie中找到sessionKey,并赋值给sid
    if (cookies != null) {
      for (int i = 0; i < cookies.length; i++)
      {
        Cookie cookie = cookies[i];
        if (cookie.getName().equals(this.sessionKey))
        {
          sid = cookie.getValue();
          break;
        }
      }
    }
    String ip = IpUtil.getIpAddress(request);
    int ipHash = ip.hashCode();
    String sessionId = generateSessionString(ipHash);
    if (StringUtils.isBlank(sid))
    {
      resetSessionIdValueInCookie(response, sessionId);
      sid = sessionId;
    }
    else
    {
      String[] sessionIdArr = sid.split("!");
      if ((sessionIdArr != null) && (sessionIdArr.length == 2) && (!StringUtils.equals(String.valueOf(ipHash), sessionIdArr[1])))
      {
        resetSessionIdValueInCookie(response, sessionId);
        sid = sessionId;
      }
    }
    //每次请求都会new一个新的,所以session永远不会过期
    ClusterHttpServletRequestWrapper clusterHttpServletRequest = new ClusterHttpServletRequestWrapper(this.servletContext, request, sid, this.sessionService);
    ClusterHttpSessionWrapper clusterHttpSessionWrapper = (ClusterHttpSessionWrapper)clusterHttpServletRequest.getSession();
    //String userName = (String) clusterHttpSessionWrapper.getAttribute(SessionSecurityConstants.KEY_USER_NAME);
    //System.out.println("ClusterSessionFilter拦截器中session中username的值为"+userName);
    //利用过滤器,将session由ClusterHttpServletRequestWrapper控制
    chain.doFilter(clusterHttpServletRequest, servletResponse);
    if (clusterHttpSessionWrapper != null) {
      clusterHttpSessionWrapper.saveSession();
    }
    //System.out.println("111session创建时间"+clusterHttpSessionWrapper.getCreationTime());
    
  }
  
  //添加cookie
  private void resetSessionIdValueInCookie(HttpServletResponse response, String sessionId)
  {
    Cookie cookie = new Cookie(this.sessionKey, sessionId);
    cookie.setMaxAge(-1);
    if (StringUtils.isNotBlank(this.cookieDomain)) {
      cookie.setDomain(this.cookieDomain);
    }
    cookie.setPath(this.cookiePath);
    response.addCookie(cookie);
  }
  
  //生成sessionid
  private String generateSessionString(int ipHash)
  {
    return UUID.randomUUID().toString() + "!" + ipHash;
  }
  
  public void destroy() {}
}
